// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Nav/WGINavType.h"
#include "Input/InputType.h"
#include "Input/InputConfigureLibrary.h"
#include "WGIUserWidget.generated.h"


DECLARE_LOG_CATEGORY_EXTERN(WGI_UserWidgetLog, Log, All);

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnDestructEvent, UWGI_UserWidget*, Widget);

class UPanelWidget;
class UHorizontalBox;
class UVerticalBox;
class UScrollBox;
class UGridPanel;
class UUniformGridPanel;




/**
 *
 */
UCLASS()
class WIDGETGROUP_API UWGI_UserWidget : public UUserWidget
{
	GENERATED_BODY()

public:


	UWGI_UserWidget(const FObjectInitializer& ObjectInitializer);

	virtual void BeginDestroy() override;


	/**
	 * Actual effect -- AddToViewport, 但是需要处理WidgetGroup的创建顺序
	 *
	 * - bRemoveLast: true ,最后打开的小部件将被删除.
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Viewport", meta = (Keywords = "Add To", AdvancedDisplay = "bRemoveLast"))
		void AddWidgetToViewport(bool bRemoveLast = false);

	/**
	 * Actual effect -- RemoveFromParent, 但是需要处理WidgetGroup的创建顺序
	 *
	 * - bRemoveAll: true ,这将删除组中的所有小部件.
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Viewport", meta = (Keywords = "Remove From", AdvancedDisplay = "bRemoveAll"))
		void RemoveWidgetFromViewport(bool bRemoveAll = false);

	/**
	 * 当这个界面中有动态添加的WGIUserWidget时，需要再调用一次这个函数，将动态添加的界面保存至内部，将用于按键消息的发送
	 * 在这个动态界面被删除时，不需要进行其他操作
	 *
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (Keywords = "Remove From", AdvancedDisplay = "bRemoveAll"))
		void AddChildWGIUserWidget(UPARAM(ref)UWGI_UserWidget*& Widget);

	void OnReloadConfigEvent();
protected:
	//当界面被移除时
	UPROPERTY(BlueprintAssignable)
		FOnDestructEvent DestructEvent;

	UFUNCTION()
		void ChildWGIUserWidgetOnRemoved(UWGI_UserWidget* Widget);

	FScriptDelegate BindUFunctionToDelegate(const FName UFunctionName);

	virtual void NativeConstruct() override;
	virtual void NativeDestruct() override;
	virtual FReply NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;
	virtual FReply NativeOnKeyUp(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;
	virtual void NativeOnFocusLost(const FFocusEvent& InFocusEvent) override;


	/**
	 * 默认为空
	 * 添加之后将会阻断 对导航的Enter事件
	 */
	UFUNCTION(BlueprintImplementableEvent, Category = "WGI|KeyEvent")
		void EnterKeyEvent(const FGeometry& InGeometry, bool isDown);
	/**
	 * 默认为移除界面
	 * 添加之后将会阻断关闭界面，所以需要手动添加 移除界面
	 */
	UFUNCTION(BlueprintImplementableEvent, Category = "WGI|KeyEvent")
		void BackKeyEvent(const FGeometry& InGeometry, bool isDown);

	/**
	 * 如果为true，在界面被打开时将会扫描所有子界面并覆盖子界面部分设置以方便使用焦点。
	 * 如果为false，那么将需要手动设置每个子界面的相关焦点设置
	 */
	 //UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "WGI")
	bool bOverrideAllChildSetting;
	/**
	 * 重置界面焦点
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI")
		void ResetFocus();
	UFUNCTION()
		void ResetFocusFromInputKeySelector(FInputChord SelectedKey) { ResetFocus(); }


	void OverrideChildWidgetFocus(UWidget* inParentWidget);
	bool OverridePanelWidget(UWidget* inWidget);
	bool SetButtonFocusable(UWidget* inWidget);
	bool SetCheckBoxFocusable(UWidget* inWidget);
	bool SetScrollBoxFocusable(UWidget* inWidget);
	bool SetSliderFocusable(UWidget* inWidget);
	bool SetComboBoxFocusable(UWidget* inWidget);
	bool SetInputKeySelector(UWidget* inWidget);
	bool OverrideUserWidget(UWidget* inWidget, bool bAddToChildWGI = true);


	TArray<UWGI_UserWidget*> ChildWGIUserWidget;

	bool EnterKeyToNav(const FKeyEvent& InKeyEvent);
	void EnterUpToNav(WGINavPanelData*& NavData);
	void EnterDownToNav(WGINavPanelData*& NavData);
	void EnterRightToNav(WGINavPanelData*& NavData);
	void EnterLeftToNav(WGINavPanelData*& NavData);
	int SelectItemInPanel(int SelectIndex, UPanelWidget* Panel);
	int SelectItemInPanel(int SelectIndex, UPanelWidget* Panel, FNavDelegate* Delegate);
	void UnSelectItemInPanel(int SelectIndex, UPanelWidget* Panel);
	void UnSelectItemInPanel(int SelectIndex, UPanelWidget* Panel, FNavDelegate* Delegate);
	void SelectLast_SingleRow(WGINavPanelData*& NavData);
	void SelectNext_SingleRow(WGINavPanelData*& NavData);
	void SelectLeft_FourDirections(WGINavPanelData*& NavData);
	void SelectRight_FourDirections(WGINavPanelData*& NavData);
	void SelectUp_FourDirections(WGINavPanelData*& NavData);
	void SelectDown_FourDirections(WGINavPanelData*& NavData);
	void CallOnSelectEvent(UWidget* Child);
	void CallOnSelectEvent(UWidget* Child, FNavDelegate* Delegate);
	void CallOnUnSelectEvent(UWidget* Child);
	void CallOnUnSelectEvent(UWidget* Child, FNavDelegate* Delegate);
	void CallClickEvent(WGINavPanelData*& NavData);

public:

	/**
	 * 向 Horizontal Box 面板添加一个按键导航
	 *
	 * - HorizontalBox: 要添加导航的面板
	 * - LeftKey: 向左的按键组名称
	 * - RightKey: 向右的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroHorizontalBox(UPARAM(ref)UHorizontalBox*& HorizontalBox, FName LeftKey = NAME_None, FName RightKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 Horizontal Box 面板添加一个按键导航
	 *
	 * - HorizontalBox: 要添加导航的面板
	 * - OnClickedEvent: 按键通知
	 * - OnSelectedEvent: 选择通知
	 * - OnUnSelectedEvent: 取消选择通知
	 * - LeftKey: 向左的按键组名称
	 * - RightKey: 向右的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroHorizontalBox_Delegate(UPARAM(ref)UHorizontalBox*& HorizontalBox, FOnNavClickedEvent OnClickedEvent, FOnNavSelectedEvent OnSelectedEvent, FOnNavUnSelectedEvent OnUnSelectedEvent,
			FName LeftKey = NAME_None, FName RightKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 Vertical Box 面板添加一个按键导航
	 *
	 * - VerticalBox: 要添加导航的面板
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroVerticalBox(UPARAM(ref)UVerticalBox*& VerticalBox, FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 Vertical Box 面板添加一个按键导航
	 *
	 * - VerticalBox: 要添加导航的面板
	 * - OnClickedEvent: 按键通知
	 * - OnSelectedEvent: 选择通知
	 * - OnUnSelectedEvent: 取消选择通知
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroVerticalBox_Delegate(UPARAM(ref)UVerticalBox*& VerticalBox, FOnNavClickedEvent OnClickedEvent, FOnNavSelectedEvent OnSelectedEvent, FOnNavUnSelectedEvent OnUnSelectedEvent,
			FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 Scroll Box 面板添加一个按键导航
	 *
	 * - ScrollBox: 要添加导航的面板
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroScrollBox(UPARAM(ref)UScrollBox*& ScrollBox, FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 Scroll Box 面板添加一个按键导航
	 *
	 * - ScrollBox: 要添加导航的面板
	 * - OnClickedEvent: 按键通知
	 * - OnSelectedEvent: 选择通知
	 * - OnUnSelectedEvent: 取消选择通知
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroScrollBox_Delegate(UPARAM(ref)UScrollBox*& ScrollBox, FOnNavClickedEvent OnClickedEvent, FOnNavSelectedEvent OnSelectedEvent, FOnNavUnSelectedEvent OnUnSelectedEvent,
			FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 GridPanel 面板添加一个按键导航
	 *
	 * - GridPanel: 要添加导航的面板
	 * - MaxColumn: 面板每行最大列数
	 * - LeftKey: 向左的按键组名称
	 * - RightKey: 向右的按键组名称
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroGridPanel(UPARAM(ref)UGridPanel*& GridPanel, int MaxColumn, FName LeftKey = NAME_None, FName RightKey = NAME_None, FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 GridPanel 面板添加一个按键导航
	 *
	 * - GridPanel: 要添加导航的面板
	 * - MaxColumn: 面板每行最大列数
	 * - OnClickedEvent: 按键通知
	 * - OnSelectedEvent: 选择通知
	 * - OnUnSelectedEvent: 取消选择通知
	 * - LeftKey: 向左的按键组名称
	 * - RightKey: 向右的按键组名称
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroGridPanel_Delegate(UPARAM(ref)UGridPanel*& GridPanel, int MaxColumn, FOnNavClickedEvent OnClickedEvent, FOnNavSelectedEvent OnSelectedEvent, FOnNavUnSelectedEvent OnUnSelectedEvent,
			FName LeftKey = NAME_None, FName RightKey = NAME_None, FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 UniformGridPanel 面板添加一个按键导航
	 *
	 * - UniformGridPanel: 要添加导航的面板
	 * - MaxColumn: 面板每行最大列数
	 * - LeftKey: 向左的按键组名称
	 * - RightKey: 向右的按键组名称
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroUniformGridPanel(UPARAM(ref)UUniformGridPanel*& UniformGridPanel, int MaxColumn, FName LeftKey = NAME_None, FName RightKey = NAME_None, FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);
	/**
	 * 向 UniformGridPanel 面板添加一个按键导航
	 *
	 * - UniformGridPanel: 要添加导航的面板
	 * - MaxColumn: 面板每行最大列数
	 * - OnClickedEvent: 按键通知
	 * - OnSelectedEvent: 选择通知
	 * - OnUnSelectedEvent: 取消选择通知
	 * - LeftKey: 向左的按键组名称
	 * - RightKey: 向右的按键组名称
	 * - UpKey: 向上的按键组名称
	 * - DownKey: 向下的按键组名称
	 * - bIsLoop: 这个面板是否可以循环导航
	 * - InitSelectedIndex: 默认选择的项 （将会触发 OnSelectEvent）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav", meta = (AdvancedDisplay = "bIsLoop, InitSelectedIndex"))
		void AddNavFroUniformGridPanel_Delegate(UPARAM(ref)UUniformGridPanel*& UniformGridPanel, int MaxColumn, FOnNavClickedEvent OnClickedEvent, FOnNavSelectedEvent OnSelectedEvent, FOnNavUnSelectedEvent OnUnSelectedEvent,
			FName LeftKey = NAME_None, FName RightKey = NAME_None, FName UpKey = NAME_None, FName DownKey = NAME_None, bool bIsLoop = false, int InitSelectedIndex = 0);


	/**
	 * 激活这个面板的按键导航事件
	 * 请先确保这个面板的按键导航已经被添加
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void ActiveThisNav(UPARAM(ref)UPanelWidget*& PanelWidget);
	/**
	 * 关闭这个面板的按键导航事件
	 * 如果不在需要一个面板的按键导航，推荐使用 RemoveThisNav();
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void UnActiveThisNav(UPARAM(ref)UPanelWidget*& PanelWidget);
	/**
	 * 移除这个面板的按键导航事件
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void RemoveThisNav(UPARAM(ref)UPanelWidget*& PanelWidget);


	/**
	 * 为特定的导航面板添加子物件
	 * 如果在添加之前面板没有子物件，那么将会自动执行这个所添加的子物件的Select事件
	 *
	 * - Panel: 特定的导航面板
	 * - Content: 所添加的子物件
	 * - bSelectThis: 在添加之后选中他
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action", meta = (AdvancedDisplay = "bSelectThis"))
		UPanelSlot* AddChildToNavPanel(UPARAM(ref)UPanelWidget*& Panel, UWidget* Content, bool bSelectThis = false);
	/**
	 * 为特定的GridPanel导航面板添加子物件
	 * 如果在添加之前面板没有子物件，那么将会自动执行这个所添加的子物件的Select事件
	 *
	 * - Panel: 特定的导航面板
	 * - Content: 所添加的子物件
	 * - bSelectThis: 在添加之后选中他
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action", meta = (AdvancedDisplay = "bSelectThis"))
		UPanelSlot* AddChildToNavPanel_GridPanel(UPARAM(ref)UPanelWidget*& Panel, UWidget* Content, bool bSelectThis = false);
	/**
	 * 移除特定导航面板的子物件
	 * 当移除了被选中的子物件，那么将会自动选择临近的子物件执行Select事件
	 *
	 * - Panel: 特定的导航面板
	 * - Content: 移除的子物件
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void RemoveChildFromNavPanel(UPARAM(ref)UPanelWidget*& Panel, UWidget* Content);
	/**
	 * 移除特定GridPanel导航面板的子物件
	 * 当移除了被选中的子物件，那么将会自动选择临近的子物件执行Select事件
	 *
	 * - Panel: 特定的导航面板
	 * - Content: 移除的子物件
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void RemoveChildFromNavPanel_GridPanel(UPARAM(ref)UPanelWidget*& Panel, UWidget* Content);
	/**
	 * 移除特定导航面板当前选中的子物件
	 *
	 * - Panel: 特定的导航面板
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void RemoveSelectedFromNavPanel(UPARAM(ref)UPanelWidget*& Panel);
	/**
	 * 移除特定GridPanel导航面板当前选中的的子物件
	 *
	 * - Panel: 特定的导航面板
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void RemoveSelectedFromNavPanel_GridPanel(UPARAM(ref)UPanelWidget*& Panel);
	/**
	 * 清理导航面板子物件
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void ClearChildrenOfNavPanel(UPARAM(ref)UPanelWidget*& Panel);
	/**
	 * 选择子物件，再子物件没有被选中时，将会执行 OnSelectEvent
	 *
	 * - bCallEventWhenSelected: 是否在子物件已经被选中的情况下继续执行 Select Event
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		void SelectItemAtNavPanel(UPARAM(ref)UPanelWidget*& Panel, int SelectIndex, bool bCallEventWhenSelected = false, bool bJoinTheCache = false);


	/**
	 * 获取当前选中的子物件
	 *
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		UWidget* GetSelectedItemFromNavPanel(UPARAM(ref)UPanelWidget*& Panel);
	/**
	 * 获取当前选中的子物件索引
	 *
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|Nav|Action")
		int GetSelectedIndexFromNavPanel(UPARAM(ref)UPanelWidget*& Panel);

protected:
	TArray<WGINavPanelData*> NavDatas;

	bool GetExistingByPanelData(UPanelWidget* Panel, WGINavPanelData*& OutData);
	WGINavPanelData* Ex_AddNavFroPanel(UPanelWidget* Panel, EWGINavPanelType PanelType, bool bIsLoop, int InitSelectedIndex);


public:
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void BindEnterKeyToNav(UPARAM(ref)UPanelWidget*& NavPanel);
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void UnBindEnterKey();

	/**
	 * 添加一个按键的事件
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void AddKeyEvent(FName KeyName, FOnKeyDownEvent OnKeyDownEvent, FOnKeyUpEvent OnKeyUpEvent);
	/**
	 * 添加一个按下按键的事件
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void AddKeyDownEvent(FName KeyName, FOnKeyDownEvent OnKeyDownEvent);
	/**
	 * 添加一个弹起按键的事件
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void AddKeyUpEvent(FName KeyName, FOnKeyUpEvent OnKeyUpEvent);


	/**
	 * 激活这个按键事件的按下和弹起
	 * 请先确保这个按键事件已经被添加
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void ActiveThisKey(FName KeyName);
	/**
	 * 激活这个按键事件的按下事件
	 * 请先确保这个按键事件已经被添加
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void ActiveThisKeyDown(FName KeyName);
	/**
	 * 激活这个按键事件的弹起事件
	 * 请先确保这个按键事件已经被添加
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void ActiveThisKeyUp(FName KeyName);
	/**
	 * 关闭这个按键事件的按下和弹起
	 * 如果不再需要这个按键事件，推荐使用 RemoveThisKey();
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void UnActiveThisKey(FName KeyName);
	/**
	 * 关闭这个按键事件的按下事件
	 * 如果不再需要这个按键事件，推荐使用 RemoveThisKey();
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void UnActiveThisKeyDown(FName KeyName);
	/**
	 * 关闭这个按键事件的弹起事件
	 * 如果不再需要这个按键事件，推荐使用 RemoveThisKey();
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void UnActiveThisKeyUp(FName KeyName);
	/**
	 * 删除这个按键事件的按下和弹起
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void RemoveThisKey(FName KeyName);
	/**
	 * 删除这个按键事件的按下事件
	 * 如果不再需要这个按键事件，推荐使用 RemoveThisKey();
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void RemoveThisKeyDown(FName KeyName);
	/**
	 * 删除这个按键事件的弹起事件
	 * 如果不再需要这个按键事件，推荐使用 RemoveThisKey();
	 *
	 * - KeyName: 按键组名称 （不支持Enter和Back）
	 */
	UFUNCTION(BlueprintCallable, BlueprintCosmetic, Category = "WGI|KeyEvent")
		void RemoveThisKeyUp(FName KeyName);

protected:
	bool EnterKeyDownToCutom(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent);
	bool EnterKeyUpToCutom(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent);

	TMap<FName, FCustomKeyDelegateGroup*> CutomKeyEvents;

private:
	WGINavPanelData* NavDataCache;
	WGINavPanelData* EnterKeyNav;
};

